﻿using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Reflection;
using System.Security.Claims;
using WMS_IBLL;
using WMS_Tools.Model;
using WMS_Tools.Common;
using WMS_DATABASE_MYSQL.MappingClass.SystemClass;
using Microsoft.AspNetCore.Authorization;
using System.Data;


namespace WMS_WEBAPI.Controllers.Base
{
    [ApiController]
    [Route("[controller]/[action]")]
    public class AccountController : ControllerBase
    {
        private readonly ILogger<AccountController> _logger;
        private readonly string controllerName;
        private readonly IConfiguration _configuration;
        private readonly ISysAuthorityIBLL _sysAuthorityIBLL;
        public AccountController(ILogger<AccountController> logger, ISysAuthorityIBLL sysAuthorityIBLL, IConfiguration configuration)
        {
            _logger = logger;
            controllerName = GetType().Name;
            _sysAuthorityIBLL = sysAuthorityIBLL;
            _configuration = configuration;
        }
        [HttpPost]
        //post请求[FromBody]标记参数为对象需要使用json的格式进行传递，然后postman在"Body"框下选择"raw"，参数类型不要写错
        public async Task<IActionResult> LoginAsync([FromBody] LoginModel person)
        {
            var t = MethodBase.GetCurrentMethod();
            string? methodName = t?.Name;
            var md5key = MD5Encode.GetMD5Encode(person.password, "utf-8");
            var u = await _sysAuthorityIBLL.QueryListAsync(a => a.loginname == person.username && a.password == md5key);
            if (u.Count ==1)
            {
                var loginobject = u.First();
                _logger.LogInformation($"{controllerName}控制器{methodName}方法,执行成功：{DateTime.Now}");
                var claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, person.username),
                    new Claim(ClaimTypes.Role,loginobject.authoritykey==0?"admin":"user")
                };
                var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
                await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));
                loginobject.password = "***";
                return Ok(new LoginRegisterResultModel()
                {
                    status = "ok",
                    type = "account",
                    currentAuthority = person.username=="admin"?"admin":"user",
                    loginname = person.username,
                    realname= loginobject.realname,
                    avatar = loginobject.avatarpath,
                    access= loginobject.access,
                    notifyCount = loginobject.notifyCount,
                    unreadCount = loginobject.unreadCount,
                    mobilephone = loginobject.mobilephone,
                    email = loginobject.email,
                    dept=loginobject.dept,
                    section=loginobject.section,
                    group=loginobject.group,
                    pwdstrength=loginobject.pwdstrength,
                });
            }
            else
            {
                return Ok(new LoginRegisterResultModel()
                {
                    status= "error",
                    type="account",
                    currentAuthority="guest",
                });
            }
        }

        [HttpPost]
        public async Task<IActionResult> LogoutAsync()
        {
            var t = MethodBase.GetCurrentMethod();
            string? methodName = t?.Name;
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            _logger.LogInformation($"{controllerName}控制器{methodName}方法,执行成功：{DateTime.Now}");
            return Ok("成功退出");
        }

        [HttpPost]
        //post请求[FromBody]标记参数为对象需要使用json的格式进行传递，然后postman在"Body"框下选择"raw"，参数类型不要写错
        public async Task<IActionResult> RegisterAsync([FromBody] LoginModel person)
        {
            var u = await _sysAuthorityIBLL.QueryListAsync(a => a.loginname == person.username);
            if (u.Count>0)
            {
                return Ok(new LoginRegisterResultModel()
                {
                    status = "repeat",
                    type = "register",
                });
            }
            else
            {
                wms_sysauthority register = new wms_sysauthority();
                register.pwdstrength =person.password.GetPwdStrength();
                register.loginname = person.username;
                register.password = MD5Encode.GetMD5Encode(person.password, "utf-8");
                register.avatarpath= _configuration.GetSection("DefaultAvatarName").Value ?? "ganda.jpg"; ;
                //register.avatarpath = "ganda.jpg";//这是注册默认的头像图片名称
                var isaddsucess = await _sysAuthorityIBLL.CreateAsync(register);
                if (isaddsucess)
                {
                    _logger.LogInformation($"Account控制器Register方法,执行成功：{DateTime.Now}");
                    return Ok(new LoginRegisterResultModel()
                    {
                        status = "ok",
                        type = "register",
                    });
                }
                else
                {
                    _logger.LogError($"Account控制器Register方法,执行失败-数据库操作失败：{DateTime.Now}");
                    return Ok(new LoginRegisterResultModel()
                    {
                        status = "error",
                        type = "register",
                    });
                }
            }
        }
        [HttpPut]
        public async Task<IActionResult> ModifyPwdAsync([FromBody] wms_sysauthority row)
        {
            //先选出你要编辑的账户名
            var youraccount = await _sysAuthorityIBLL.QueryListAsync(a => a.loginname == row.loginname);
            
            row.password = MD5Encode.GetMD5Encode(row.password, "utf-8");
            //头像路径还是保持原来的账户的头像
            if (youraccount.Count == 1)
            {
                youraccount.First().password = row.password;
                //获得密码强度
                youraccount.First().pwdstrength=row.password.GetPwdStrength();
                var iseditsucess = await _sysAuthorityIBLL.EditAsync(youraccount.First());
                if (iseditsucess)
                {
                    _logger.LogInformation($"Account控制器editAccount方法,执行成功：{DateTime.Now}");
                    return Ok("编辑成功");
                }
                else
                {
                    _logger.LogError($"Account控制器editAccount方法,执行失败-数据库操作失败：{DateTime.Now}");
                    return BadRequest("编辑失败");
                }
            }
            else
            {
                _logger.LogError($"Account控制器editAccount方法,执行失败-数据库未查询出{row.loginname}结果：{DateTime.Now}");
                return BadRequest("有重复用户");
            }
        }
        [HttpPost]
        public async Task<IActionResult> AvarterUploadAsync([FromForm] IFormFile avatar, [FromForm] string loginname)
        {
            //先获得上传图片的名称
            var fileName = avatar.FileName;
            //获得图片保存的地址
            var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "AvarterUpload", fileName);
            //如果图片不存在则复制
            if (!System.IO.File.Exists(path))
            {
                //复制图片到保持的地址
                using (var stream = new FileStream(path, FileMode.Create))
                {
                    avatar.CopyTo(stream);
                }
            }
           
            //先查询数据库中此用户名的数据，然后修改数据中图片名称，改为上传后的图片名称，再存入数据库中
            var u = await _sysAuthorityIBLL.QueryListAsync(a => a.loginname == loginname);
            if (u.Count == 1)
            {
                u.First().avatarpath = avatar.FileName;
                var iseditsucess = await _sysAuthorityIBLL.EditAsync(u.First());
                if (iseditsucess)
                {
                    _logger.LogInformation($"Account控制器Upload方法,执行成功：{DateTime.Now}");
                    u.First().password = "***";
                    return Ok(200);
                }
                else
                {
                    _logger.LogError($"Account控制器Upload方法,执行失败-数据库操作失败：{DateTime.Now}");
                    return BadRequest("头像上传失败");
                }
            }
            else
            {
                _logger.LogError($"Account控制器Upload方法,执行失败-数据库未查询出{loginname}结果：{DateTime.Now}");
                return BadRequest("头像上传失败");
            }

        }


        //以下为管理员及以上角色才能使用的方法
        [Authorize(Roles ="superadmin,admin")]
        [HttpGet]
        public async Task<IActionResult> GetAccountAsync(int page, int pagesize)
        {
            var data = await _sysAuthorityIBLL.ToPageListAsync(page, pagesize);
            var datacount = data.Count();
            return Ok(new { data, total = datacount });
        }

        [Authorize(Roles = "superadmin,admin")]
        [HttpPost]
        public async Task<IActionResult> AddAccountAsync([FromBody] wms_sysauthority row)
        {
            var data = await _sysAuthorityIBLL.QueryListAsync(a => true);
            var namelist = data.Select(a => a.loginname).ToList();
            //判断是否有重复的用户名
            var isdoublesn = namelist.Contains(row.loginname);
            if (!isdoublesn)
            {
                row.password = MD5Encode.GetMD5Encode(row.password, "utf-8");
                var isaddsucess = await _sysAuthorityIBLL.CreateAsync(row);
                if (isaddsucess)
                {
                    _logger.LogInformation($"Account控制器addAccount方法,执行成功：{DateTime.Now}");
                    return Ok("添加成功");
                }
                else
                {
                    _logger.LogError($"Account控制器addAccount方法,执行失败-数据库操作失败：{DateTime.Now}");
                    return BadRequest("添加失败");
                }
            }
            else
            {
                _logger.LogError($"Account控制器addAccount方法,执行失败-用户名重复：{DateTime.Now}");
                return BadRequest("用户名重复");
            }

        }
        [Authorize(Roles = "superadmin")]
        [HttpPut]
        public async Task<IActionResult> ModifyAuthorizationAsync([FromBody] wms_sysauthority row)
        {
            //先选出你要编辑的账户名
            var youraccount = await _sysAuthorityIBLL.QueryListAsync(a => a.loginname == row.loginname);
            if (youraccount.Count == 1)
            {
                youraccount.First().authoritykey = row.authoritykey;
                var iseditsucess = await _sysAuthorityIBLL.EditAsync(youraccount.First());
                if (iseditsucess)
                {
                    _logger.LogInformation($"Account控制器ModifyAuthorization方法,执行成功：{DateTime.Now}");
                    return Ok("编辑成功");
                }
                else
                {
                    _logger.LogError($"Account控制器ModifyAuthorization方法,执行失败-数据库操作失败：{DateTime.Now}");
                    return BadRequest("编辑失败");
                }
            }
            else
            {
                _logger.LogError($"Account控制器ModifyAuthorization方法,执行失败-数据库未查询出{row.loginname}结果：{DateTime.Now}");
                return BadRequest("无此用户");
            }
        }
        [Authorize(Roles = "superadmin")]
        [HttpDelete]
        public async Task<IActionResult> DelAccountAsync(int key)
        {
            var data = await _sysAuthorityIBLL.QueryListAsync(a => a.key == key);
            if (data.Count==1)
            {
                var isdelsuccess = await _sysAuthorityIBLL.DeleteByIdAsync(key);
                if (isdelsuccess)
                {
                    _logger.LogInformation($"Account控制器delAccount方法,参数为{key}执行成功：{DateTime.Now}");
                    return Ok("删除成功");
                }
                else
                {
                    _logger.LogError($"Account控制器delAccount方法,参数为{key}执行失败：{DateTime.Now}");
                    return BadRequest("删除失败");
                }
            }
            else
            {
                _logger.LogInformation($"Account控制器delAccount方法,参数为{key}执行失败-找不到数据：{DateTime.Now}");
                return BadRequest("无此用户");
            }

        }

        [HttpPut]
        public async Task<IActionResult> ModifyBaseSettingAsync([FromBody] wms_sysauthority row)
        {
            //先选出你要编辑的账户名
            var youraccount = await _sysAuthorityIBLL.QueryListAsync(a => a.loginname == row.loginname);

            //头像路径还是保持原来的账户的头像
            if (youraccount.Count == 1)
            {
                youraccount.First().realname = row.realname;
                youraccount.First().dept = row.dept;
                youraccount.First().section = row.section;
                youraccount.First().group = row.group;
                youraccount.First().mobilephone = row.mobilephone;
                youraccount.First().email = row.email;
                var iseditsucess = await _sysAuthorityIBLL.EditAsync(youraccount.First());
                if (iseditsucess)
                {
                    _logger.LogInformation($"Account控制器ModifyBaseSetting方法,执行成功：{DateTime.Now}");
                    return Ok("编辑成功");
                }
                else
                {
                    _logger.LogError($"Account控制器ModifyBaseSetting方法,执行失败-数据库操作失败：{DateTime.Now}");
                    return BadRequest("编辑失败");
                }
            }
            else
            {
                _logger.LogError($"Account控制器ModifyBaseSetting方法,执行失败-数据库未查询出{row.loginname}结果：{DateTime.Now}");
                return BadRequest("有重复用户");
            }
        }

        [HttpGet]
        public IActionResult NoAuthResult()
        {
            _logger.LogInformation("没有权限");
            return BadRequest("没有权限");
        }

    }
}
